# -*- coding: utf-8 -*-
import scrapy,re
from scrapy.http import Request
from urllib import parse
from ArticleSpider.items import JobBoleArticleItem
from ArticleSpider.utils.common import get_md5
from ArticleSpider.items import ArticleItemLoader
# https://www.jianshu.com/p/e71ff6173302   pipelines解释
class JobboleSpider(scrapy.Spider):
    name = 'jobbole'
    allowed_domains = ['blog.jobbole.com']
    start_urls = ['http://blog.jobbole.com/all-posts/']
    #parse方法是scrapy.Spider中必须实现的方法，会默认调用此方法
    def parse(self, response):
        """
        1.获取文章列表中文章url并交给scrapy下载后并解析
        2.获取下一页的url并交给scrapy下载，下载完成后交给parse
        """
        #获取所有文章链接
        post_nodes=response.css("#archive .floated-thumb .post-thumb a")
        for post_node in post_nodes:
            #parse用于解析url，urljoin可以从第一个参数中提取域名，从第二个参数中提取路径然后拼接
            post_url=parse.urljoin(response.url,post_node.css("::attr(href)").extract_first(""))
            image_url=post_node.css("img::attr(src)").extract_first("")
            #meta参数用于传递多余的参数
            yield Request(url=post_url,meta={"front_image_url":image_url},callback=self.parse_detail)#请求url后将内容使用回调函数解析，yield是一部方式
        #获取下一页的url
        next_urls=response.css(".next.page-numbers::attr(href)").extract_first("")#如果获取不到就给默认值""
        if next_urls:#如果下一页存在就执行回调
            yield Request(url=next_urls,callback=self.parse)

    #解析具体文章的内容
    def parse_detail(self,response):
        front_image_url=response.meta["front_image_url"]#字典取值的另一种方式response.meta.get("front_image_url","")获取不到的情况下不会抛出异常会返回默认值
        #通过Item Loader来填充Item
        #ArticleItemLoader是继承了ItemLoader后的重构如果不重构应该是ItemLoader(item=JobBoleArticleItem(),response=response)
        item_loader = ArticleItemLoader(item=JobBoleArticleItem(),response=response)# item数据模型实例，response需要解析的数据
        item_loader.add_xpath('title','//div[@class="entry-header"]/h1/text()')
        item_loader.add_xpath('create_date','//p[@class="entry-meta-hide-on-mobile"]/text()')
        item_loader.add_xpath('praise_nums','//span[contains(@class,"vote-post-up")]/h10/text()')
        item_loader.add_xpath('fav_nums','//span[contains(@class,"bookmark-btn")]/text()')
        item_loader.add_xpath('comment_nums','//a[@href="#article-comment"]/span/text()')
        item_loader.add_xpath('content','//div[@class="entry"]')
        item_loader.add_xpath('tags','//p[@class="entry-meta-hide-on-mobile"]/a/text()')
        item_loader.add_value('url',response.url)
        item_loader.add_value('url_object_id',get_md5(response.url))
        item_loader.add_value('front_image_url',[front_image_url])
        article_item = item_loader.load_item()
        yield article_item #执行异步操作后数据会经过pipelines进行过滤，在这里可以对数据进行加工
